package com.iwdnb.gkgz.common.utils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.iwdnb.bmnf.common.utils.BeanConvertUtils;
import com.iwdnb.gkgz.common.model.dto.StockDayData;
import com.iwdnb.gkgz.common.model.dto.StockMinuteData;
import com.iwdnb.gkgz.common.model.dto.StockPredictionCheckInfo;
import com.iwdnb.gkgz.common.model.dto.StockPredictionData;
import com.iwdnb.gkgz.common.model.dto.prediction.StockIncomePrediction;
import com.iwdnb.gkgz.common.model.dto.prediction.StockPredictionParam;
import com.iwdnb.gkgz.common.model.dto.prediction.StockPredictionStatistics;
import com.iwdnb.gkgz.common.prediction.PredictionStrategy;
import com.iwdnb.gkgz.common.prediction.PredictionStrategyFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

@Slf4j
public class StockIncomeUtils {


    /**
     * 计算预测收益
     *
     * @param stockDayDataList
     * @return
     */
    public static List<StockIncomePrediction> caculatePredictionIncome(List<StockDayData> stockDayDataList) {
        if (CollectionUtils.isEmpty(stockDayDataList)) {
            return null;
        }
        StockDayData firstData = stockDayDataList.get(0);
        if (!StockIgnoreUtils.isYearEnable(firstData.getCode(), firstData.getDate().substring(0, 4))) {
            return null;
        }

        List<StockMinuteData> historyMinuteData = null;
        //if (firstData.getDate().startsWith(DateUtil.format(new Date(), "yyyy"))) {
        //    historyMinuteData = StockUtils.queryHistoryMinuteData(firstData.getCode(),
        //        Lists.newArrayList(30, 60));
        //}
        BigDecimal total = new BigDecimal(0);
        BigDecimal buyPrice = stockDayDataList.get(0).getClosePrice();
        BigDecimal sellPrice = null;
        boolean first = true;
        int sleepCount = 0;
        List<BigDecimal> notSellBuyList = new ArrayList<>();
        List<StockIncomePrediction> stockIncomePredictions = new ArrayList<>();
        for (
            int i = 0; i < stockDayDataList.size(); i++) {
            StockDayData data = stockDayDataList.get(i);
            StockIncomePrediction stockIncomePrediction = BeanConvertUtils.convert(data, StockIncomePrediction.class);
            stockIncomePredictions.add(stockIncomePrediction);

            StockPredictionCheckInfo checkInfo = data.getCheckInfo();
            StockPredictionData prediction = data.getTodayPrediction();
            BigDecimal sy = null;
            BigDecimal maxPrice = prediction.getMaxPrice();
            BigDecimal minPrice = prediction.getMinPrice();
            stockIncomePrediction.setPredictionMaxPrice(maxPrice);
            stockIncomePrediction.setPredictionMinPrice(minPrice);
            stockIncomePrediction.setBuyPrice(buyPrice);
            boolean upFlag = data.getOpenPrice().compareTo(data.getClosePrice()) <= 0;
            String info = upFlag ? "上涨" : "下跌";
            BigDecimal rangePrice = data.getOpenPrice().subtract(data.getClosePrice()).abs();

            String matchType = "";
            BigDecimal yesterdayBuyPrice = buyPrice;
            if (checkInfo.isMatchAll()) {
                matchType = "全匹配";
                sy = maxPrice.subtract(buyPrice);
                if (CollectionUtils.isNotEmpty(notSellBuyList)) {
                    BigDecimal temp = sellStoreStock(data.getDate(), notSellBuyList, maxPrice);
                    sy = sy.add(temp);
                    notSellBuyList = new ArrayList<>();
                }
                buyPrice = minPrice;
                sellPrice = maxPrice;
            } else if (checkInfo.isMatchSell()) {
                matchType = "匹配出售价";
                //买入价以下午2.30的基准价买入,暂处理以收盘价买入
                sellPrice = maxPrice;
                sy = sellPrice.subtract(buyPrice);
                buyPrice = data.getClosePrice().add(new BigDecimal("0.003"));
            } else if (checkInfo.isMatchBuy()) {
                matchType = "匹配买入价";
                //卖出价以上午10.30的基准价卖出,暂处理以收盘价卖出
                sellPrice = data.getClosePrice().subtract(new BigDecimal("0.003"));
                sy = sellPrice.subtract(buyPrice);
                buyPrice = minPrice;
            } else {
                //以收盘价卖出，收盘价买入
                sy = data.getClosePrice().subtract(buyPrice);
                matchType = "未匹配";
                buyPrice = data.getClosePrice();
                sellPrice = data.getClosePrice();
            }
            //log.info(
            //    "{} {}  真实股价信息:开盘价={},收盘价={},涨跌:{},最高价={},最低价={},预测匹配:{},预测出售价:{},预测买入价:{},上次买入价:{},真实出售价:{},"
            //        + "真实买入价:{},收益:{},截止昨日总收益:{}",
            //    data.getDate(), info, data.getOpenPrice(), data.getClosePrice(), info + rangePrice,
            //    data.getMaxPrice(), data.getMinPrice(), matchType,
            //    maxPrice, minPrice, yesterdayBuyPrice, sellPrice, buyPrice, sy,
            //    total);
            stockIncomePrediction.setUpDownInfo(info + rangePrice);
            stockIncomePrediction.setMatchType(matchType);
            stockIncomePrediction.setRealSellPrice(sellPrice);
            stockIncomePrediction.setRealBuyPrice(buyPrice);
            stockIncomePrediction.setIncome(sy);
            if (!first) {
                total = total.add(sy);
            } else {
                first = false;
            }
        }
        //log.info("{} {}总收益为{}", firstData.getCode(), firstData.getDate(), total);
        return stockIncomePredictions;
    }



    public static BigDecimal caculatePredictionTotalIncome(List<StockIncomePrediction> stockIncomePredictions) {
        BigDecimal total = new BigDecimal(0);
        if (CollectionUtils.isEmpty(stockIncomePredictions)) {
            return total;
        }
        for (StockIncomePrediction prediction : stockIncomePredictions) {
            total = total.add(prediction.getIncome());
        }
        return total;
    }

    public static StockPredictionParam getDefaultPredictionParam() {
        StockPredictionParam param = new StockPredictionParam();
        param.setStrategyName("defaultPredictionStrategy");
        param.setMaxTotalHighDivideNum(new BigDecimal("7.94"));
        param.setMaxTotalLowDivideNum(new BigDecimal("8"));
        param.setMaxRangeFirstThreshold(new BigDecimal("0.03"));
        param.setMaxRangeSecondThreshold(new BigDecimal("0.05"));
        param.setMaxRangeRate(new BigDecimal("1.5"));
        param.setMaxRangeFirstRate(new BigDecimal("1.7"));
        param.setMaxRangeSecondRate(new BigDecimal("2.2"));
        param.setMinTotalHighDivideNum(new BigDecimal("7.93"));
        param.setMinTotalLowDivideNum(new BigDecimal("8"));
        param.setMinRangeFirstThreshold(new BigDecimal("0.03"));
        param.setMinRangeSecondThreshold(new BigDecimal("0.05"));
        param.setMinRangeRate(new BigDecimal("1"));
        param.setMinRangeFirstRate(new BigDecimal("1.5"));
        param.setMinRangeSecondRate(new BigDecimal("1.9"));
        return param;
    }


    /**
     * 出售库存股票
     *
     * @param buyPriceList
     * @param sellPrice
     */
    private static BigDecimal sellStoreStock(String date, List<BigDecimal> buyPriceList, BigDecimal sellPrice) {
        BigDecimal sy = new BigDecimal(0);
        for (BigDecimal buyPrice : buyPriceList) {
            sy = sy.add(sellPrice).subtract(buyPrice);
        }
        log.info("{} 出售库存股票,真实出售价:{},真实买入价:{},收益:{}", date, sellPrice,
            buyPriceList, sy);
        return sy;
    }

}
